import { AudioClip, AudioSource, director, Node, resources } from 'cc';

export class AudioManager {
    static #instance: AudioManager;
    public static get instance(): AudioManager {
        if (!this.#instance) this.#instance = new AudioManager();
        return this.#instance;
    }

    private audioSource: AudioSource;
    private constructor() {
        let audioMgr = new Node();
        audioMgr.name = '__AudioManager__';
        director.getScene().addChild(audioMgr);
        director.addPersistRootNode(audioMgr);
        this.audioSource = audioMgr.addComponent(AudioSource);
    }

    public playOneShot(sound: AudioClip | string, volume: number = 1.0) {
        if (sound instanceof AudioClip) {
            this.audioSource.playOneShot(sound, volume);
            return;
        }
        resources.load(sound, (err, clip: AudioClip) => {
            if (err) throw Error('AudioManager load sound failed; ' + err);
            this.audioSource.playOneShot(clip, volume);
        });
    }

    private _play(sound: AudioClip, loop: boolean, volume: number): void {
        this.audioSource.stop();
        this.audioSource.clip = sound;
        this.audioSource.loop = !!loop;
        this.audioSource.play();
        this.audioSource.volume = volume;
    }
    public play(sound: AudioClip | string, loop: boolean, volume: number = 1.0) {
        if (sound instanceof AudioClip) {
            this._play(sound, loop, volume);
            return;
        }

        resources.load(sound, (err, clip: AudioClip) => {
            if (err) throw Error('AudioManager load sound failed; ' + err);
            this._play(clip, loop, volume);
        });
    }

    public stop() {
        this.audioSource.stop();
    }
    public pause() {
        this.audioSource.pause();
    }
    public resume() {
        this.audioSource.play();
    }
}
